// #include"block_queue.hpp"
// #include"Task.hpp"
// #include<pthread.h>
// #include<ctime>
// #include<sys/types.h>
// #include<unistd.h>


// void *consumer(void *args)
// {
//     block_queue<Task> *bq=static_cast<block_queue<Task>* >(args);
//     while(true)
//     {
//         sleep(1);
//         Task t;

//         //取出任务
//         bq->Pop(&t);
//         t();//运行任务

//         std::cout<<"consumer data: "<<t.PrintResult()<<std::endl;
//     }
//     return nullptr;
// }

// void *producror(void *args)
// {
//     block_queue<Task> *bq=static_cast<block_queue<Task>*>(args);

//     while(true)
//     {
//         //sleep(1);
//         int x=rand()%10;
//         usleep(rand()%123);
//         int y=rand()%10;
//         usleep(rand()%1234);
//         char oper=opers[rand()%(opers.size())];
//         Task t(x,y,oper);
//         std::cout<<"productor data: "<<t.PrintTask()<<std::endl;
//         bq->Push(t);
//     }
//     return nullptr;
// }

// int main()
// {
//     srand((uint16_t)time(nullptr) ^ getpid() ^ pthread_self()); // 只是为了形成更随机的数据
//     block_queue<Task> *bq=new block_queue<Task>();
//     pthread_t c,p;
//     pthread_create(&c,nullptr,consumer,bq);
//     pthread_create(&p,nullptr,producror,bq);
//     pthread_join(c,nullptr);
//     pthread_join(p,nullptr);
//     return 0;
// }

#include"ringqueue.hpp"
#include "Task.hpp"
#include <unistd.h>
#include <pthread.h>
#include <ctime>

void *Productor(void *args)
{
    // sleep(5);
    RingQueue<Task> *rq = static_cast<RingQueue<Task> *>(args);
    while (true)
    {
        // 数据怎么来的？
        // 1. 有数据，从具体场景中来，从网络中拿数据
        // 生产前，你的任务从哪里来的呢？？？
        int data1 = rand() % 10; // [1, 10] // 将来深刻理解生产消费，就要从这里入手，TODO
        usleep(rand() % 123);
        int data2 = rand() % 10; // [1, 10] // 将来深刻理解生产消费，就要从这里入手，TODO
        usleep(rand() % 123);
        char oper = opers[rand() % (opers.size())];
        Task t(data1, data2, oper);
        std::cout << "productor task: " << t.PrintTask() << std::endl;

        // rq->push();
        rq->Push(t);

         sleep(1);
    }
}

void *Consumer(void *args)
{
    RingQueue<Task> *rq = static_cast<RingQueue<Task> *>(args);
    while (true)
    {
        // sleep(1);

        Task t;
        rq->Pop(&t);

        t();
        std::cout << "consumer done, data is : " << t.PrintResult() << std::endl;
    }
}

int main()
{

    srand((uint64_t)time(nullptr) ^ pthread_self());
    pthread_t c[3], p[2];

    // 唤醒队列中只能放置整形？？？
    // RingQueue<int> *rq = new RingQueue<int>();
    RingQueue<Task> *rq = new RingQueue<Task>();

    pthread_create(&p[0], nullptr, Productor, rq);
    pthread_create(&p[1], nullptr, Productor, rq);
    pthread_create(&c[0], nullptr, Consumer, rq);
    pthread_create(&c[1], nullptr, Consumer, rq);
    pthread_create(&c[2], nullptr, Consumer, rq);

    pthread_join(p[0], nullptr);
    pthread_join(p[1], nullptr);
    pthread_join(c[0], nullptr);
    pthread_join(c[1], nullptr);
    pthread_join(c[2], nullptr);

    return 0;
}